package com.csust.automaticteach.app.teacher.iflytek.ppt;

import org.apache.commons.codec.binary.Base64;
import org.springframework.stereotype.Component;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * @ClassNameAuthentication
 * @Description iflytek 鉴权类
 * @Author钰玟
 * @Date2025/7/17 下午10:54
 * @Version 1.0
 **/
@Component
public class Authentication {
    /**
     * 获取签名
     *
     * @param appId     签名的key
     * @param apiSecret 签名秘钥
     * @param ts        时间戳.
     * @return The generated signature.
     */

    public String getSignature(String appId, String apiSecret, long ts) {
        try {
            String auth = md5(appId + ts);
            return hmacSHA1Encrypt(auth, apiSecret);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            // Log the exception for debugging
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 使用HMAC-SHA1算法生成消息认证码(MAC)。
     *
     * @param encryptText 需要加密的文本。
     * @param encryptKey  用于加密的密钥。
     * @return 生成的加密字符串，以Base64编码格式返回。
     * @throws NoSuchAlgorithmException 如果系统不支持HMAC-SHA1算法。
     * @throws InvalidKeyException      如果提供的密钥无效。
     */
    private String hmacSHA1Encrypt(String encryptText, String encryptKey)
            throws NoSuchAlgorithmException, InvalidKeyException {
        // 将密钥转换为UTF-8字节，并创建HMAC-SHA1规格的密钥
        SecretKeySpec keySpec = new SecretKeySpec(
                encryptKey.getBytes(StandardCharsets.UTF_8), "HmacSHA1");

        // 获取HMAC-SHA1算法的Mac实例
        Mac mac = Mac.getInstance("HmacSHA1");
        // 初始化Mac实例
        mac.init(keySpec);

        // 对输入文本进行加密处理，得到加密后的字节数组
        byte[] result = mac.doFinal(encryptText.getBytes(StandardCharsets.UTF_8));

        // 将加密结果转换为Base64编码字符串并返回
        return Base64.encodeBase64String(result);
    }

    /**
     * 对传入的文本进行MD5加密，返回16进制字符串形式的哈希值。
     * 用于生成基于MD5的消息摘要，常用于数据完整性校验。
     *
     * @param text 需要进行MD5加密的原始文本字符串
     * @return 加密后的MD5哈希值，以16进制字符串形式表示
     * @throws NoSuchAlgorithmException 如果运行环境中缺少MD5算法实现
     */
    private String md5(String text) throws NoSuchAlgorithmException {
        // 获取MD5消息摘要实例
        MessageDigest md = MessageDigest.getInstance("MD5");
        // 执行摘要处理，将输入字符串转换为字节数组后进行加密
        byte[] digestBytes = md.digest(text.getBytes(StandardCharsets.UTF_8));

        // 创建StringBuilder用于拼接16进制字符串
        StringBuilder hexString = new StringBuilder();
        // 遍历加密后的字节数组，转换为16进制字符串
        for (byte b : digestBytes) {
            // 使用String.format格式化字节为两位16进制数
            String hex = String.format("%02x", b);
            // 拼接至最终结果字符串
            hexString.append(hex);
        }
        // 返回完整的MD5哈希字符串
        return hexString.toString();
    }
}
